import { defineStore } from 'pinia'
import { useAuthStore } from './auth'
import { BellFilled, Close } from '@element-plus/icons-vue'
import { createVNode, render } from 'vue'
import { ElIcon } from 'element-plus'

export const useWebSocketStore = defineStore('websocket', {
    state: () => ({
        ws: null,
        isConnected: false,
        reconnectTimer: null,
        reconnectInterval: 3000,
        maxReconnectInterval: 30000,
        reconnectCount: 0,
        maxReconnectCount: 5,
        currentRoute: '',
        clientId: '',
        lastAuthState: {
            token: '',
            userId: ''
        },
        lastToken: '',
        lastUserId: '',
        notificationList: [], // 存储所有通知ID，用于批量管理
        isClearingNotifications: false,
        notificationSpacing: 12, // 通知之间的间距（px）
        singleNotificationHeight: 86 // 单个通知高度（含padding和border）
    }),
    actions: {
        /**
         * 初始化WebSocket
         * @param {string} initialRoute - 初始路由
         */
        initWebSocket(initialRoute) {
            this.currentRoute = initialRoute || ''
            this.watchAuthChange()
            this.watchRouteChange()
            this.watchTokenUpdate()
            // 初始化时检查路由，若已在登录页则清理通知
            if (this.currentRoute === '/login') {
                this.clearAllNotifications()
            }
        },

        /**
         * 监听主进程发送的token更新事件
         */
        watchTokenUpdate() {
            if (window.electron?.ipcRenderer) {
                window.electron.ipcRenderer.on('token-updated', () => {
                    const authStore = useAuthStore()
                    console.log('🔄 websocketStore: 收到token更新通知，尝试重连')
                    this.handleAuthChange(authStore.token, authStore.userId)
                })
            } else {
                console.warn('⚠️ websocketStore: 无法监听token更新（ipcRenderer不可用）')
            }
        },

        /**
         * 监听认证状态变化（登录/登出）
         */
        watchAuthChange() {
            const authStore = useAuthStore()

            this.lastAuthState = {
                token: authStore.token,
                userId: authStore.userId
            }

            this.handleAuthChange(authStore.token, authStore.userId)

            authStore.$subscribe((mutation, state) => {
                const newAuthState = {
                    token: state.token,
                    userId: state.userId
                }
                const isAuthChanged = JSON.stringify(newAuthState) !== JSON.stringify(this.lastAuthState)

                if (isAuthChanged) {
                    console.log('🔍 websocketStore: 关键认证信息变化（userId/token）', {
                        old: this.lastAuthState,
                        new: newAuthState
                    })

                    this.lastAuthState = newAuthState
                    this.handleAuthChange(newAuthState.token, newAuthState.userId)
                } else {
                    console.log('ℹ️ websocketStore: 非关键用户信息变化（忽略）')
                }
            })
        },

        /**
         * 处理认证状态变化（建立/断开连接）
         */
        handleAuthChange(token, userId) {
            if (this.lastToken === token && this.lastUserId === userId) {
                return;
            }
            this.lastToken = token;
            this.lastUserId = userId;

            console.log('\n🔍 websocketStore: 认证状态变化', {
                hasToken: !!token,
                hasUserId: !!userId,
                isConnected: this.isConnected
            })

            // 有完整认证信息且未连接 → 建立连接
            if (token && userId && !this.isConnected) {
                this.connectWebSocket(token, userId)
            }
            // 认证信息缺失且已连接 → 断开连接
            else if ((!token || !userId) && this.isConnected) {
                this.disconnectWebSocket()
            }
        },

        /**
         * 监听路由变化
         */
        watchRouteChange() {
            const router = this.$router
            if (router) {
                this.currentRoute = router.currentRoute.value?.path || ''
                router.afterEach((to) => {
                    const prevRoute = this.currentRoute
                    this.currentRoute = to.path || ''
                    // 从非登录页切换到登录页时，清理所有通知
                    if (prevRoute !== '/login' && this.currentRoute === '/login' && !this.isClearingNotifications) {
                        console.log('🔄 路由切换到登录页，执行通知清理')
                        this.clearAllNotifications()
                    }
                })
            }
        },

        /**
         * 建立WebSocket连接
         */
        connectWebSocket(token, userId) {
            if (this.isConnected) return

            // 关闭旧连接
            if (this.ws) {
                this.ws.close(1000, '准备建立新连接')
                this.ws = null
            }

            // 构建连接地址
            const wsUrl = `ws://39.100.95.39:6001/websocket/${userId}`;
            console.log('🌐 websocketStore: 尝试连接', wsUrl)

            try {
                this.ws = new WebSocket(wsUrl)

                // 连接成功
                this.ws.onopen = () => {
                    console.log('✅ websocketStore: 连接建立成功')
                    this.isConnected = true
                    this.clearReconnectTimer()
                    this.reconnectCount = 0 // 重置重连计数
                }

                // 接收消息
                this.ws.onmessage = (event) => {
                    try {
                        const message = event.data?.trim() || ''
                        console.log('📩 websocketStore: 收到消息', message)

                        // 尝试解析JSON
                        let parsedMessage;
                        try {
                            parsedMessage = JSON.parse(message);
                        } catch (e) {
                            console.log('📩 非JSON消息:', message);
                            // 处理非JSON消息
                            if (message.includes('新增每日课程安排')) {
                                this.showGlobalNotification(message);
                            }
                            return;
                        }

                        // 处理解析后的JSON消息
                        if (parsedMessage.type === 'add' && parsedMessage.dailyCourseSchedule) {
                            // 格式化日期
                            const courseDate = new Date(parsedMessage.dailyCourseSchedule.courseDate);
                            const formattedDate = courseDate.toLocaleDateString('zh-CN', {
                                year: 'numeric',
                                month: 'long',
                                day: 'numeric'
                            });

                            // 格式化时间
                            const startTime = new Date(parsedMessage.dailyCourseSchedule.startTime);
                            const endTime = new Date(parsedMessage.dailyCourseSchedule.endTime);
                            const formattedTime = `${startTime.toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit' })} - ${endTime.toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit' })}`;

                            // 构建通知消息
                            const notificationMessage = `
                                <div class="notification-details">
                                    <div>班级: ${parsedMessage.classInfo?.className || '未知班级'}</div>
                                    <div>日期: ${formattedDate} ${formattedTime}</div>
                                    ${parsedMessage.dailyCourseSchedule.notes ? `<div>课程内容: ${parsedMessage.dailyCourseSchedule.notes}</div>` : ''}
                                </div>
                            `;

                            this.showGlobalNotification(notificationMessage);
                        }
                    } catch (err) {
                        console.error('❌ websocketStore: 处理消息失败', err)
                    }
                }

                // 连接关闭
                this.ws.onclose = (event) => {
                    console.log(`🔌 websocketStore: 连接关闭`, {
                        code: event.code,
                        reason: event.reason
                    })
                    this.isConnected = false

                    // 非主动关闭且有认证信息 → 重连
                    if (event.code !== 1000) {
                        const authStore = useAuthStore()
                        if (authStore.token && authStore.userId) {
                            console.log('🔄 websocketStore: 连接断开，准备重连')
                            this.startReconnect()
                        }
                    }
                }

                // 连接错误
                this.ws.onerror = (err) => {
                    console.error('❌ websocketStore: 连接错误', err)
                    this.isConnected = false
                    const authStore = useAuthStore()
                    if (authStore.token && authStore.userId) {
                        this.startReconnect()
                    }
                }
            } catch (err) {
                console.error('❌ websocketStore: 创建实例失败', err)
                this.isConnected = false
                const authStore = useAuthStore()
                if (authStore.token && authStore.userId) {
                    this.startReconnect()
                }
            }
        },

        /**
         * 显示全局通知（带手动关闭和堆叠功能）
         */
        showGlobalNotification(message, type = 'info') {
            // 登录页不显示通知
            if (this.currentRoute === '/login') {
                return;
            }

            // 生成唯一通知ID
            const notificationId = `notification-${Date.now()}`;
            this.notificationList.push(notificationId);

            // 创建通知容器
            const notification = document.createElement('div');
            notification.id = notificationId;
            notification.className = 'custom-notification';

            // 计算当前通知的top位置（避免叠加）
            const activeNotifications = document.querySelectorAll('.custom-notification:not(.custom-notification-fade-out)');
            const topOffset = 20 + (activeNotifications.length * (this.singleNotificationHeight + this.notificationSpacing));
            notification.style.top = `${topOffset}px`;

            // 渲染通知图标
            const bellIconVNode = createVNode(ElIcon, { class: 'custom-notification-icon' }, {
                default: () => createVNode(BellFilled)
            });
            const bellIconContainer = document.createElement('span');
            render(bellIconVNode, bellIconContainer);

            // 渲染关闭图标（带点击事件）
            const closeContainer = document.createElement('span');
            closeContainer.className = 'custom-notification-close-container';

            const closeIconVNode = createVNode(ElIcon, { class: 'custom-notification-close-icon' }, {
                default: () => createVNode(Close)
            });
            render(closeIconVNode, closeContainer);

            // 绑定关闭事件
            const closeHandler = () => {
                this.closeNotification(notificationId);
                // 从列表中移除
                this.notificationList = this.notificationList.filter(id => id !== notificationId);
            };
            closeContainer.addEventListener('click', closeHandler);

            // 设置通知内容
            const contentContainer = document.createElement('div');
            contentContainer.className = 'custom-notification-content';
            contentContainer.innerHTML = message;

            // 组装通知
            notification.appendChild(bellIconContainer);
            notification.appendChild(contentContainer);
            notification.appendChild(closeContainer);

            // 添加到页面
            document.body.appendChild(notification);
        },

        /**
         * 调整所有活跃通知的垂直位置（避免关闭后出现空隙）
         */
        adjustNotificationPositions() {
            const activeNotifications = document.querySelectorAll('.custom-notification:not(.custom-notification-fade-out)');

            activeNotifications.forEach((notification, index) => {
                const topOffset = 20 + (index * (this.singleNotificationHeight + this.notificationSpacing));
                notification.style.top = `${topOffset}px`;
            });
        },

        /**
         * 关闭单个通知
         * @param {string} notificationId - 通知ID
         */
        closeNotification(notificationId) {
            const notification = document.getElementById(notificationId);
            if (!notification) return;

            // 添加淡出动画
            notification.classList.add('custom-notification-fade-out');

            // 动画结束后移除元素并调整位置
            setTimeout(() => {
                if (document.body.contains(notification)) {
                    // 清理Vue虚拟节点
                    const iconContainers = notification.querySelectorAll('span');
                    iconContainers.forEach(container => render(null, container));

                    // 移除DOM元素
                    document.body.removeChild(notification);

                    // 调整剩余通知位置
                    this.adjustNotificationPositions();
                }
            }, 300); // 与CSS过渡时间一致
        },

        /**
         * 清理所有通知（用于退出登录或切换到登录页）
         */
        clearAllNotifications() {
            if (this.isClearingNotifications) {
                console.log('ℹ️ 通知清理已在执行中，跳过重复调用')
                return;
            }

            this.isClearingNotifications = true;
            console.log(`🗑️ 开始清理通知，共${this.notificationList.length}个`);

            try {
                // 逐个关闭所有通知
                this.notificationList.forEach(notificationId => {
                    this.closeNotification(notificationId);
                });

                // 清空列表（动画结束后再清空，避免冲突）
                setTimeout(() => {
                    this.notificationList = [];
                }, 300); // 与关闭动画时长一致
            } catch (err) {
                console.error('❌ 清理通知失败:', err);
            } finally {
                // 无论成功失败，都重置清理状态（300ms后，确保动画完成）
                setTimeout(() => {
                    this.isClearingNotifications = false;
                }, 300);
            }
        },

        /**
         * 启动重连机制
         */
        startReconnect() {
            this.clearReconnectTimer()
            const authStore = useAuthStore()
            if (authStore.token && authStore.userId) {
                // 指数退避重连策略
                const nextInterval = Math.min(
                    this.reconnectInterval * Math.pow(2, this.reconnectCount),
                    this.maxReconnectInterval
                );

                this.reconnectTimer = setTimeout(() => {
                    console.log(`🔄 websocketStore: 第${this.reconnectCount + 1}次重连（间隔${nextInterval / 1000}秒）`)
                    this.reconnectCount++;
                    this.connectWebSocket(authStore.token, authStore.userId)
                }, nextInterval)
            }
        },

        /**
         * 清除重连定时器
         */
        clearReconnectTimer() {
            if (this.reconnectTimer) {
                clearTimeout(this.reconnectTimer)
                this.reconnectTimer = null
            }
        },

        /**
         * 断开WebSocket连接
         */
        disconnectWebSocket() {
            if (this.ws) {
                console.log('🔌 websocketStore: 主动断开连接')
                this.ws.close(1000, '认证失效或页面卸载')
                this.ws = null
            }
            this.isConnected = false
            this.clearReconnectTimer()
        },

        /**
         * 销毁WebSocket资源
         */
        destroyWebSocket() {
            this.disconnectWebSocket()
            this.currentRoute = ''
            // 仅当“未在清理中”时执行（避免与其他场景重复）
            if (!this.isClearingNotifications) {
                this.clearAllNotifications()
            }
        },
    },
})
